<script setup lang="ts">
import { computed, reactive, ref, watch, onMounted, onBeforeUnmount } from 'vue'
import { Promotion, Sugar, Plus } from '@element-plus/icons-vue'
import { useAmsStore } from '@/stores/ams'
import useWebSocket from './useWebSocket'
import { WsReadyState } from '@/utils/websocket.core'
import { ElMessage } from 'element-plus'
import VueJsonPretty from 'vue-json-pretty'
import 'vue-json-pretty/lib/styles.css'

const amsStore = useAmsStore()

interface qaItem {
  index: number
  question: string
  ask: string
  askType: string //todo 不能确定的响应类型，后续等产品稳定后有时间再来统一梳理这里
}
const question = ref('')
const asking = ref('') // 回答中
const showAskingDiv = ref(false) // 显示回答中的div
const chatList = reactive<qaItem[]>([])
const quickInst = ref('')

const wsUri = `ws://${window.location.hostname}:${window.location.port}/api/ams/ws/chat`

const { status, send, reconnect, close } = useWebSocket(wsUri, {
  autoConnect: true,
  onMessage: (data) => {
    const chatOutDto = JSON.parse(data)
    switch (chatOutDto.msgType) {
      case 'ping':
        break
      case 'asking': // 流式回复中
        if (chatOutDto.response == 'hcy end') {
          console.log('流式回复结束')
        } else {
          asking.value += chatOutDto.response.replace(/\n/g, '<br>')
        }
        break
      case 'resq':
        try {
          chatList[chatList.length - 1].ask = JSON.parse(chatOutDto.response)
          chatList[chatList.length - 1].askType = 'resq'
        } catch (_) {
          chatList[chatList.length - 1].ask = chatOutDto.response
          chatList[chatList.length - 1].askType = 'errResq'
        }

        break
      case 'err':
        // ElMessage.error(chatOutDto.response)
        // chatList[chatList.length - 1].ask = chatOutDto.response
        // chatList[chatList.length - 1].askType = 'errResq'
        break
      default:
        ElMessage.error('未知消息：' + chatOutDto.response)
        break
    }
  },
})

const clickSendMsg = () => {
  if (question.value.trim()) {
    send({
      isAi: isAi.value,
      msgType: 'inst',
      question: question.value.trim(),
      clientId: amsStore.currClient.id,
      timestamp: Date.now() + '',
    })
    chatList.push({
      index: Date.now(),
      question: question.value.trim(),
      ask: '',
      askType: 'resq',
    })
    question.value = ''
    asking.value = ''
    showAskingDiv.value = true
  }
}

watch(
  () => [amsStore.chatDrawerShow],
  ([newchatDrawerShow], [oldchatDrawerShow]) => {
    console.log('状态变化 chatDrawerShow:', newchatDrawerShow, oldchatDrawerShow)
    if (newchatDrawerShow) {
      if (status.value != WsReadyState.OPEN) reconnect()
    } else {
      close()
    }
  },
)

onMounted(() => {
  console.log('准备初始化socketio,onMounted')
})
onBeforeUnmount(() => {
  console.log('onBeforeUnmount 关闭ws')
  if (status.value == WsReadyState.OPEN) close()
})

const options = [
  {
    value: '举手',
    label: '举手',
  },
  {
    value: '重启',
    label: '重启',
  },
  {
    value: '获取唯一码',
    label: '获取唯一码',
  },
  {
    value: '更新策略',
    label: '更新策略',
  },
  {
    value: '上传插件信息',
    label: '上传插件信息',
  },
]
const isAi = ref(false)
const aiDivClass = computed(() => {
  return isAi.value ? 'ai-style' : 'inst-style'
})
</script>

<template>
  <el-drawer v-model="amsStore.chatDrawerShow" direction="rtl">
    <template #header>
      <h4>{{ amsStore.currClient.hostname }}</h4>
    </template>
    <template #default>
      <div class="">
        <div class="h-[80vh] overflow-y-auto">
          <div v-for="item in chatList" :key="item.index">
            <div class="flex flex-col mt-2">
              <div class="ml-auto">
                <span class="span-c">{{ item.question }}</span>
              </div>
              <div class="w-fit mt-3 que-div">
                <!-- <div v-if="item.askType == 'errResq'">客户端响应</div>
                <div v-else>客户端响应</div> -->
                <vue-json-pretty
                  v-model:data="item.ask"
                  :deep="3"
                  :show-double-quotes="true"
                  :show-line="true"
                  :show-line-number="false"
                  :editable="false"
                />
              </div>
            </div>
          </div>
          <div class="w-fit mt-3 que-div" v-show="showAskingDiv" v-html="asking"></div>
        </div>
        <div class="absolute bottom-2 left-1 right-1">
          <el-input
            v-model="question"
            :autosize="{ minRows: 3, maxRows: 5 }"
            type="textarea"
            placeholder="输入需要发送的指令，AI模式可以使用自然语言对话"
          />
          <div class="flex justify-between items-center">
            <div>
              <el-select v-model="quickInst" placeholder="常用指令" style="width: 100px">
                <el-option
                  v-for="item in options"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                />
              </el-select>
              <el-button :icon="Sugar" :class="aiDivClass" @click="isAi = !isAi">AI赋能</el-button>
            </div>
            <div>
              <el-button :icon="Plus">文件推送</el-button>
              <el-button :icon="Promotion" class="ml-auto" @click="clickSendMsg">发送</el-button>
            </div>
          </div>
        </div>
      </div>
    </template>
  </el-drawer>
</template>

<style scoped>
.que-div {
  color: #000;
  background-color: #e4e6eb;
  border-radius: 10px;
  padding: 0.42em 0.55em;
  line-height: 1.26em;
}
.span-c {
  color: #fff;
  background-color: #0084ff;

  border-radius: 10px;
  padding: 0.42em 0.55em;
  line-height: 1.26em;
}
.ai-style {
  color: rgb(8, 231, 38);
}
.inst-style {
  color: rgb(100, 90, 90);
}
.el-drawer__header {
  margin-bottom: 0px;
}
</style>
